﻿Imports System.Xml
Imports System.Xml.Serialization
Imports System.Runtime.Serialization

Namespace Collections

    <XmlRoot("Dictionary")> _
    Public Class SerializableDictionary(Of TKey, TValue)
        Inherits Dictionary(Of TKey, TValue)
        Implements IXmlSerializable

        Public Sub New()
            MyBase.New()
        End Sub

        Public Sub New(ByVal dictionary As IDictionary(Of TKey, TValue))
            MyBase.New(dictionary)
        End Sub

        Public Sub New(ByVal comparer As IEqualityComparer(Of TKey))
            MyBase.New(comparer)
        End Sub

        Public Sub New(ByVal capacity As Integer)
            MyBase.New(capacity)
        End Sub

        Public Sub New(ByVal capacity As Integer, ByVal comparer As IEqualityComparer(Of TKey))
            MyBase.New(capacity, comparer)
        End Sub

#If (Not WINDOWS_PHONE) And (Not NETFX_CORE) Then

        Protected Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
            MyBase.New(info, context)
        End Sub

#End If

        Public Function GetDictionary() As Dictionary(Of TKey, TValue)
            Dim result As New Dictionary(Of TKey, TValue)
            Dim item As KeyValuePair(Of TKey, TValue)
            For Each item In Me
                result.Add(item.Key, item.Value)
            Next
            Return result
        End Function

        Public Sub ReadXml(ByVal reader As XmlReader) Implements IXmlSerializable.ReadXml
            Dim keySerializer As New XmlSerializer(GetType(TKey))
            Dim valueSerializer As New XmlSerializer(GetType(TValue))
            Dim wasEmpty As Boolean = reader.IsEmptyElement
            reader.Read()
            If Not wasEmpty Then
                Do While (reader.NodeType <> XmlNodeType.EndElement)
                    reader.ReadStartElement("Key")
                    Dim key As TKey = DirectCast(keySerializer.Deserialize(reader), TKey)
                    reader.ReadEndElement()
                    reader.ReadStartElement("Value")
                    Dim value As TValue = DirectCast(valueSerializer.Deserialize(reader), TValue)
                    reader.ReadEndElement()
                    MyBase.Add(key, value)
                    reader.MoveToContent()
                Loop
                reader.ReadEndElement()
            End If
        End Sub

        Public Sub WriteXml(ByVal writer As XmlWriter) Implements IXmlSerializable.WriteXml
            Dim keySerializer As New XmlSerializer(GetType(TKey))
            Dim valueSerializer As New XmlSerializer(GetType(TValue))
            Dim key As TKey
            For Each key In MyBase.Keys
                writer.WriteStartElement("Key")
                keySerializer.Serialize(writer, key)
                writer.WriteEndElement()
                writer.WriteStartElement("Value")
                Dim value As TValue = MyBase.Item(key)
                valueSerializer.Serialize(writer, value)
                writer.WriteEndElement()
            Next
        End Sub

        Public Function GetSchema() As Schema.XmlSchema Implements IXmlSerializable.GetSchema
            Throw New NotImplementedException()
        End Function

    End Class

End Namespace